#ifndef __thinvm__
#define __thinvm__

#include "../bochs.h"
#include "../cpu/cpu.h"

namespace thinvm
{
	typedef Ia32_Instruction_c	bx_instruction_t;
	typedef Bit32u				bx_uint32_t;
	typedef ExecStopReason		bx_stop_reason_t;

	enum 
	{ 
		MAX_INST_BYTES		= 16,
		MAX_PAGES_IN_2G		= (0x80000000/0x1000)-1,
	};

	enum
	{
		VMPA_READ			= IA32_READ,
		VMPA_WRITE			= IA32_WRITE,
		VMPA_EXEC			= IA32_EXEC,

		VMPA_MOA			= 0x100,
		VMPA_ZPG			= 0x200,
		VMPA_HKA			= 0x400,
		VMPA_WCPY			= 0x800,

		VMPA_IMG			= 0x1000,
		VMPA_PRIV			= 0x2000,

		VMPA_FORCE			= 0x10000,
		VMPA_API_CATCH		= 0x20000,
		VMPA_IM_WATCH		= 0x40000,	// Instruction cache invalid watch
	};

	enum 
	{
		EXT_EXCEP_API_CATCH	= 0x1000,
		EXT_EXCEP_BREAK		= 0x1001,
	};


	template < class T, class K >
	static inline T __align_big( T v, K a )
	{
		bool pad = ( v % a ) != 0;
		return (T)(v/a*a + (pad?a:0));
	}

	struct tprocess_t;
	struct tthread_t;

	struct i_thinvm_site
	{
		virtual bool		on_access_hook( tprocess_t * proc, tthread_t * thead, uint32_t addr, size_t acc, void * buffer, size_t bytes, size_t * eff ) { return false; };
		virtual void		on_condition_check( tprocess_t * proc, tthread_t * thead, size_t checkbits ) {};
		virtual void		dispatch_api_call( tprocess_t * proc, tthread_t * thead ) {};
		virtual uint32_t	resolve_import( tprocess_t * proc, const char * mod, const char * api ) { return 0; };
	};

	typedef long (* api_impl_func_t )( tprocess_t * proc, tthread_t * thead );

};


#endif